#include "testopenglwidget.h"

float vertices[] = {
    0.5f, 0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    -0.5f, 0.5f, 0.0f,

    0.5f, -0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
    -0.5f, 0.5f, 0.0f
};

float rec_vertices[] = {
    0.5f, 0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    -0.5f, 0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
};

unsigned int rec_indices[] {
    0, 1, 2,
    1, 2, 3
};

/// 顶点着色器源码
const char *vertexShaderSource = "#version 330 core\n"
        "layout (location = 0) in vec3 aPos;\n"
        "void main()\n"
        "{\n"
        "gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
        "}\0";

/// 片段着色器源码
const char *fragmentShaderSource = "#version 330 core\n"
        "out vec4 FragColor;\n"
        "void main()\n"
        "{\n"
        "FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
        "}\n\0";

TestOpenGLWidget::TestOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{

}

TestOpenGLWidget::~TestOpenGLWidget()
{
    makeCurrent();/// 调用当前状态
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
    glDeleteVertexArrays(1, &VAO);
    doneCurrent();/// 退出当前状态
}

void TestOpenGLWidget::drawShape(TestOpenGLWidget::Shape shape)
{
    m_Shape = shape;
    update();
}

void TestOpenGLWidget::setWireframe(bool wireframe)
{
    makeCurrent();
    if(wireframe) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    } else {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
    update();
    doneCurrent();
}

void TestOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    /// 绑定VBO和VAO对象
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);// VAO可以得到VBO

    /// 为当前绑定到target的缓冲区对象创建一个新的数据存储
    /// 如果data不是NULL, 则使用来自此指针的数据初始化数据存储
//    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glBufferData(GL_ARRAY_BUFFER, sizeof(rec_vertices), rec_vertices, GL_STATIC_DRAW);
    /// 告知显卡如何解析缓冲里的属性值
    /// 0 第0个属性,3个属性值,类型为float
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
    /// 开始VAO管理的第一个属性值
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
//    glBindVertexArray(0);

    bool success = false;
//    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
//    shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/shader/shapes.vert");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/shader/shapes.frag");
    success = shaderProgram.link();
    if(!success)
        qDebug() << "Err:" << shaderProgram.log();

    glGenBuffers(1, &EBO);//初始化EBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);// VAO可以得到EBO
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rec_indices), rec_indices, GL_STATIC_DRAW);//
//    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);//关闭EBO
    glBindVertexArray(0);
}

void TestOpenGLWidget::resizeGL(int w, int h)
{
    Q_UNUSED(w);
    Q_UNUSED(h);
}

void TestOpenGLWidget::paintGL()
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    shaderProgram.bind();
    glBindVertexArray(VAO);

    switch(m_Shape) {
    case Rect:
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//去索引拿数据
        break;
    default:
        break;
    }
}
